package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.dto.OrdersDto;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.mapper.OrdersMapper;
import com.itheima.reggie.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Mylinja 2021-12-22 星期三 10:49
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private UserService userService;
    @Autowired
    private AddressBookService addressBookService;
    @Autowired
    private OrderDetailService orderDetailService;

    /**
     * 提交订单方法
     *
     * @param orders 封装前端数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitOrder(Orders orders) {
        //A. 获得当前用户id, 查询当前用户的购物车数据
        Long userId = BaseContext.getCurrentId();

        //B. 根据当前登录用户id, 查询该用户的购物车
        // SQL: select * from shopping_cart where userId = ?
        LambdaQueryWrapper<ShoppingCart> query1 = new LambdaQueryWrapper<>();
        query1.eq(ShoppingCart::getUserId, userId);
        List<ShoppingCart> shoppingCarts = shoppingCartService.list(query1);
        if (shoppingCarts == null || shoppingCarts.size() == 0) {
            throw new CustomException("购物车不能为空，请重新下单");
        }

        //C. 根据地址id, 查询地址数据
        AddressBook addressBook = addressBookService.getById(orders.getAddressBookId());
        if (addressBook == null) {
            throw new CustomException("地址不能为空，请检查");
        }

        //D. 组装订单明细数据, 批量保存订单明细
        // 订单总金额
        int orderPrice = 0;
        // 通过工具类生成唯一订单id
        long orderId = IdWorker.getId();

        List<OrderDetail> orderDetails = new ArrayList<>();
        for (ShoppingCart shoppingCart : shoppingCarts) {
            OrderDetail orderDetail1 = new OrderDetail();

            // 把购物车的数据，拷贝到订单详情对象中
            BeanUtils.copyProperties(shoppingCart, orderDetail1);
            orderDetail1.setOrderId(orderId);

            // 计算订单总金额
            orderPrice += (shoppingCart.getAmount().intValue() * shoppingCart.getNumber());
            orderDetails.add(orderDetail1);
        }

        //E. 组装订单数据, 批量保存订单数据
        orders.setId(orderId);
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setStatus(2);
        orders.setAmount(new BigDecimal(orderPrice));
        orders.setUserId(userId);
        orders.setNumber(String.valueOf(orderId));
        orders.setUserName(userService.getById(userId).getName());
        orders.setConsignee(addressBook.getConsignee());
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getDetail());

        // 数据保存到订单表中
        this.save(orders);
        // 保存数据到订单详情表中
        orderDetailService.saveBatch(orderDetails);

        //F. 删除当前用户的购物车列表数据
        shoppingCartService.remove(query1);

    }

    /**
     * 用户查询所有订单
     * @param page     页码
     * @param pageSize 每页条目
     * @return 返回分页对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Page<OrdersDto> selectOrdersFromUser(int page, int pageSize) {

        // SQL: select * from orders where user_id = ? limit page, pageSize
        Page<Orders> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<Orders> query = new LambdaQueryWrapper<>();
        this.page(pageInfo, query);
        Page<OrdersDto> ordersDtoPage = new Page<>();
        BeanUtils.copyProperties(pageInfo, ordersDtoPage, "records");

        // 加工并封装ordersDtoPage中的records属性
        List<Orders> records = pageInfo.getRecords();
        List<OrdersDto> collect = records.stream().map((order) -> {
            OrdersDto ordersDto = new OrdersDto();
            BeanUtils.copyProperties(order, ordersDto);
            Long id = order.getId();
            LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(OrderDetail::getOrderId, id);
            List<OrderDetail> list = orderDetailService.list(queryWrapper);
            int sum = 0;
            for (OrderDetail detail : list) {
                sum += detail.getNumber();
            }
            ordersDto.setSumNum(sum);
            return ordersDto;
        }).collect(Collectors.toList());

        // 设置records属性
        ordersDtoPage.setRecords(collect);
        return ordersDtoPage;
    }
}
